package online.exam.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpStatus;
import online.exam.mapper.AnswerPaperMapper;
import online.exam.mapper.SubjectBankMapper;
import online.exam.mapper.TestPaperMapper;
import online.exam.pojo.AnswerPaper;
import online.exam.pojo.SubjectBank;
import online.exam.pojo.TestPaper;
import online.exam.pojo.vo.AnswerPaperVO;
import online.exam.pojo.vo.TestSubjectsVO;
import online.exam.service.AnswerPaperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author 王景煜
 */

@Service
public class AnswerPaperServiceImpl implements AnswerPaperService {

    @Autowired
    private AnswerPaperMapper answerPaperMapper;

    @Autowired
    private TestPaperMapper testPaperMapper;

    @Autowired
    private SubjectBankMapper subjectBankMapper;

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public int addAp(List<AnswerPaper> paperList) {

        for (AnswerPaper ap : paperList) {
            System.out.println(ap);
        }

        String testId = paperList.get(0).getTestId();
        Example tpExample = new Example(TestPaper.class);
        Example.Criteria tpc = tpExample.createCriteria();
        tpc.andEqualTo("testId", testId);
        List<TestPaper> tpl = testPaperMapper.selectByExample(tpExample);
        Collections.reverse(tpl);

        for (TestPaper tp : tpl) {
            System.out.println(tp);
        }

        int index = 0;
        BigDecimal sum = new BigDecimal(0);
        Date createdTime = new Date();
        int result = 0;
        for (AnswerPaper ap : paperList) {

            ap.setAnswerId(IdUtil.simpleUUID());

            TestPaper curTp = tpl.get(index);
            SubjectBank sbk = subjectBankMapper.selectByPrimaryKey(curTp.getSubject());
            if (ap.getSubjectAnswer().equals(sbk.getSubjectAnswer())) {
                ap.setSingleScale(curTp.getSingleScale());
                ap.setSumScale(sum.add(curTp.getSingleScale()));
            } else {
                BigDecimal zero = new BigDecimal(0);
                ap.setSingleScale(zero);
                ap.setSumScale(sum.add(zero));
            }
            ap.setCreatedTime(createdTime);
            result += answerPaperMapper.insert(ap);

            index++;
        }

        if (result == paperList.size())
            return HttpStatus.HTTP_OK;
        return HttpStatus.HTTP_INTERNAL_ERROR;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<AnswerPaperVO> queryApByTestId(String testId, String stuId) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("testId", testId);
        if (!StringUtils.isEmpty(stuId)) paramsMap.put("stuId", stuId);
        return answerPaperMapper.queryApByTestId(paramsMap);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Map<String, Object> queryTestPaperDetail(String testId, String clazz) {

        List<int[]> percentList = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();

        // 查询当前试卷编号下的所有题目
        Map<String, Object> map = new HashMap<>();
        map.put("testId", testId);
        if (!StringUtils.isEmpty(clazz)) map.put("clazz", clazz);
        List<TestSubjectsVO> bankList = testPaperMapper.querySubjectsByTestId(map);

        // 查询当前试卷学生所做的答案
        List<AnswerPaperVO> answerList = answerPaperMapper.queryApByTestId(map);
        if (answerList == null || answerList.size() == 0) {
            return null;
        }

        // 查看有多少学生已经做过当前试卷
        int stuDoneCount = answerPaperMapper.queryAllApByGroupStuId().size();

        System.out.println("当前已有 " + stuDoneCount + " 人做过该试卷");

        // 对答案集合进行二重循环操作，计算出每题的每个选项被选的百分比
        // 循环读取试卷中的所有试题
        for (TestSubjectsVO subject : bankList) {
            System.out.println(subject);

            // 第几题的类型
            int currentSubjectType = subject.getSubjectType();
            // 题号
            int testNo = subject.getTestNo();
            // 获取题目选项内容
            String subjectContent = subject.getSubjectContent();

            if (currentSubjectType == 1) { // 如果是1，代表单选题
                // 选项有几个，将选项分解到字符串数组中，并获取选项的个数
                int[] subjectContentArr = new int[subjectContent.split("\\|").length];
                for (int i = (testNo - 1) * stuDoneCount; i < testNo * stuDoneCount; i++) {
                    AnswerPaperVO apv = null;
                    try {
                        apv = answerList.get(i);
                    } catch (Exception e) {
                        break;
                    }
                    // 选项有几个，就循环几次，将学生的答案记录在数组中
                    for (int j = 0; j < subjectContentArr.length; j++) {
                        if (apv.getSubjectAnswer() != null && !"".equals(apv.getSubjectAnswer())) {
                            // todo 学生的答案 有主观题答案转换为数字导致报错
                            //legecy: int stuAnswer = Integer.parseInt(apv.getSubjectAnswer());

                            int stuAnswer = 0;
                            try {
                                stuAnswer = Integer.parseInt(apv.getSubjectAnswer());
                            } catch (NumberFormatException ignored) {
                                //不处理了
                            }

                            // 循环比对，是哪个选项，数组的哪个位置就增1
                            if (stuAnswer == j) {
                                subjectContentArr[j]++;
                            }
                        }
                    }
                }
                // 将答案百分比存至集合中
                percentList.add(subjectContentArr);
            } else if (currentSubjectType == 2) { // 如果是2，代表多选
                // 选项有几个，将选项分解到字符串数组中，并获取选项的个数
                int[] subjectContentArr = new int[subjectContent.split("\\|").length];
                for (int i = (testNo - 1) * stuDoneCount; i < testNo * stuDoneCount; i++) {
                    // TODO 会产生数组越界的错误
                    AnswerPaperVO apv = null;
                    try {
                        apv = answerList.get(i);
                    } catch (Exception ignored) {
                        break;
                    }
                    // 获取学生答案
                    String stuAnswer = apv.getSubjectAnswer();
                    if (stuAnswer != null && !"".equals(stuAnswer)) {
                        // 因为是多选题，所以要对学生答案进行拆解
                        String[] stuAnswerArr = stuAnswer.split("\\|");
                        for (String answer : stuAnswerArr) {
                            int currentStuAnswer = Integer.parseInt(answer);
                            // 对存放答案百分比的数组进行循环，匹配对应答案
                            for (int j = 0; j < subjectContentArr.length; j++) {
                                if (currentStuAnswer == j) {
                                    subjectContentArr[j]++;
                                }
                            }
                        }
                    }
                }
                percentList.add(subjectContentArr);
            }
        }

        for (AnswerPaperVO answer : answerList) {
            System.out.println(answer);
        }

        resultMap.put("apList", bankList);
        resultMap.put("percent", percentList);

        return resultMap;
    }

}
